/**
 * @create 2022-05-02
 * @desc plugin
 */

const calleeNames = ['log', 'error', 'warn', 'info'].map(name => `console.${name}`);

// 不需要引入
module.exports = function ({types, template}) {

    return {
        visitor: {
            CallExpression(path, state) {
                const {node} = path;
                const calleeCode = path.get('callee').toString();

                // 1. 插入了新节点后，babel 会继续遍历新节点，通过 isNewConsole 标记跳过
                // 2. jsx 节点不能直接插入，需要用 [] 包起来
                // 3. 单行的箭头行数，也不能往前插入，这里用 () 处理
                if (!node.isNewConsole && calleeNames.includes(calleeCode)) {
                    const {line, column} = node.callee.loc.start;
                    const newNode = template.expression(`console.log("[info]: line: ${line}, column: ${column}: ")`)();
                    newNode.isNewConsole = true;

                    if (path.findParent(p => p.isJSXElement())) {
                        path.replaceWith(types.arrayExpression([newNode, node]))
                        path.skip();
                    } else if (path.findParent(p => p.isArrowFunctionExpression())) {
                        const ArrowFunctionParent = path.findParent(p => p.isArrowFunctionExpression());
                        const start = ArrowFunctionParent.node.loc.start;
                        if (line === start.line) { // 判断是否是同一行
                            path.replaceWith(types.sequenceExpression([newNode, node]))
                            path.skip();
                        } else {
                            path.insertBefore(newNode);
                        }
                    } else {
                        path.insertBefore(newNode);
                    }
                }
            }
        }
    }
}